package com.wang.interview.N02_Singleton;

import com.wang.interview.tests.T1;

import java.util.concurrent.*;

/**
 * @author: wang
 * @date: 2021/7/30 10:51
 * @description: 用枚举实现 懒汉单例：根本原因，枚举在使用时才会被编译，所有属性都是 final static 即单例。
 * 枚举类的每个枚举类型在编译后都会被实例化为一个 继承自 java.lang.Enum 的类，所以枚举 不能继承 但是 可以实现接口
 *  一、使用 final static 修饰，初始化是在静态代码块中，保证类加载的时候就完成初始化，jvm 类加载是线程安全的
 *      所以用枚举实现单例是：线程安全和单例的，而且枚举自身设计可以防止反射和序列化复制对象
 *  二、枚举类型可以实现抽象方法，见下
 *  三、经过多线程测试，线程安全
 */
public class EnumSingleTon {
    public static void main(String[] args) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(10,20,5, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(5),Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
        for (int i = 0; i < 50; i++) {
            final int temp = i;
            pool.execute(new Thread(() -> {
                System.out.println(A.instance.getT1());
                System.out.println(Thread.currentThread().getName());
            },"name= "+temp));
        }
        pool.shutdown();
    }
}
enum A{
    instance;
    private T1 t1 = new T1();  // 成员变量同样是线程安全的，因为会被编译成静态

    /*A(){
        t1 = new T1();
    }*/

    public T1 getT1(){
        return t1;
    }
}

enum B{
    stu("666"){
        @Override
        public String getName() {
            return this.name()+"咋整";
        }
    };

    private String name;
    B(String name){                        // 构造器默认私有，传参，是因为编译后会被调用实例化枚举类型
        this.name = name;
    }

    public abstract String getName();      // 抽象方法
}

class C{
    public static void main(String[] args) {
        System.out.println(B.stu.getName());
    }
}